import {Ref, ref, watch} from 'vue'
import Layers from "@/lang/layers";
import {TreeNode} from "../../lang/bamboo";
import {TreeInstance} from "element-plus";

/**
 * 使用树形结构
 *
 * 本地数据和查询函数，必须指定其中一个
 */
export interface UseTree {
    /** 本地树形结构的数据 */
    options?: TreeNode[]
    /** 查询参数，变化之后触发查询 */
    where?: Record<string, any>
    /** 异步获取数据的函数 */
    provider?: (params: Record<string, any>) => Promise<TreeNode[]>
}

/**
 * 使用树形结构
 *
 * @param props - 组件入参
 * @param onchange - 数据字典变化事件
 */
export function useTree<T>(props: UseTree, onchange: (tree: TreeNode[]) => void = Layers.method()) {

    // 数据字典列表
    const tree: Ref<TreeNode[]> = ref<TreeNode>([]);

    // 数据加载状态
    const loading: Ref<boolean> = ref(false);

    /**
     * 查询远程数据字典
     */
    const reload = (params): void => {
        loading.value = true;
        props.provider(params).then(tree => {
            tree.value = tree
            onchange(tree);
        }).finally(() => {
            loading.value = false;
        });
    }

    watch(() => props.options, (val: TreeNode[]) => {
        onchange(val);
        tree.value = val;
    });

    watch(() => props.where, reload);

    if (props.provider != null) {
        reload(props.where);
    }

    if (props.options != null) {
        onchange(props.options);
        tree.value = props.options;
    }

    return {tree, loading}
}

/**
 * 使用树过滤效果
 *
 * @param instance 树对象引用
 */
export function useFilterText(instance: Ref<TreeInstance>) {

    // 过滤数值
    const filterText = ref('');

    /**
     * 过滤数据
     *
     * 当前函数触发之后，会继续触发 filterNode() 函数
     */
    const filterMethod = (text) => {
        filterText.value = text;
    }

    /**
     * 过滤数据
     *
     * filterMethod() 触发之后会自动触发当前函数
     */
    const filterNode = (value: string, data: Tree) => {
        if (!value) return true
        return data.label.includes(value)
    }

    /**
     * 侦听 filterText 的变化
     */
    watch(filterText, (val) => {
        instance.value!.filter(val);
    });

    return {filterText, filterMethod, filterNode}
}